package d2;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiCheckinRecordGetRequest;
import com.dingtalk.api.response.OapiUserListbypageResponse.Userlist;
import com.dingtalk.api.response.OapiCheckinRecordGetResponse;
import com.dingtalk.api.response.OapiCheckinRecordGetResponse.CheckinRecordVo;
import com.dingtalk.api.response.OapiCheckinRecordGetResponse.PageResult;

import cn.cybozu.api.KintoneFileList;
import cn.cybozu.api.KintoneRecord;

/**
 * DingTalk to kintone 連携
 * @author daisuke-ito
 *
 */
public class D2CheckinConnector extends D2Connector
{
	//modify
	private static final int LIMIT_USER_SIZE = 7;
	private static final long LIMIT_CHECKIN_SIZE = 100;
	
	private Date startDate  = null;
	private Date endDate = null;
	private Map<String, Userlist> users;


	public D2CheckinConnector(String appKey, String appSecret, String domain, long appId, long spaceId, String apiToken)
	{
		super(appKey, appSecret, domain, appId, spaceId, apiToken);
	}
	
	public void execute(Date startDate, Date endDate)
			throws Exception
	{

		this.startDate = startDate;
		this.endDate   = endDate;
		
		users = getAllUsers();
		int count = users.size();
		
		List<String> userIds = new ArrayList<>();
		
		for(String id: users.keySet())
		{
			userIds.add(id);
			if(userIds.size() == count)
			{
				getCheckin(userIds);
				userIds.clear();
			}
		}
		
		if(userIds.size() != 0)
		{
			getCheckin(userIds);
		}		
	}
	
	/**
	 * Checkin　dataの取得
	 * @param users
	 * @throws Exception
	 */
	private void getCheckin(List<String> userIds)
		throws Exception
	{
		DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/checkin/record/get");
		OapiCheckinRecordGetRequest request = new OapiCheckinRecordGetRequest();
		request.setUseridList(String.join(",",userIds));
		request.setSize(LIMIT_CHECKIN_SIZE);
		
		Date tmpDate = (Date)startDate.clone();
		
		while(tmpDate.compareTo(endDate) <= 0)
		{
			request.setStartTime(tmpDate.getTime());
			tmpDate = new Date(tmpDate.getTime() +  TimeUnit.DAYS.toMillis(1));
			request.setEndTime(tmpDate.getTime() - TimeUnit.SECONDS.toMillis(1));
			
			long offset = 0;
			
			for(;;)
			{
				request.setCursor(offset);
				OapiCheckinRecordGetResponse response = client.execute(request, getAccessToken());
				PageResult page = response.getResult();				
				List<CheckinRecordVo> list = page.getPageList();
				if(list.size() == 0)
				{
					break;
				}
				copyRecords(list);
				if(page.getNextCursor() == null)
				{
					break;
				}
				offset = page.getNextCursor();
			}
			
		}
	}
	/**
	 * recordのcopy
	 * @param results 
	 * @param userMap
	 * @throws Exception
	 */
	private void copyRecords(List<CheckinRecordVo> results)
		throws Exception
	{
		//kintone側の同一recordの取得
		StringBuilder builder = new StringBuilder();
		for(CheckinRecordVo result : results)
		{
			builder.append(builder.length() == 0 ? "" : " or ");
			builder.append("id = \"" + result.getCheckinTime() + "_" + result.getUserid() + "\"");
		}
		List<KintoneRecord> recs = getRecordsFromKintone(builder.toString(), new String[] {"$id", "id"});
		
		Map<String, Long> recMap = new HashMap<>();
		for(KintoneRecord rec : recs)
		{
			recMap.put(rec.getString("id"), rec.getId());
		}
		
		List<KintoneRecord> postRecs = new ArrayList<>();
		
		for(CheckinRecordVo result : results)
		{
			KintoneRecord rec = new KintoneRecord();
			
			String id = result.getCheckinTime() + "_" + result.getUserid();
			if(recMap.containsKey(id))
			{
				continue;
			}
			
			rec.setString("id", id);
			rec.setString("detail_place", result.getDetailPlace() == null ? null : "" + result.getDetailPlace());
			rec.setString("remark", result.getRemark()== null ? null : "" + result.getRemark());
			rec.setString("place", result.getPlace() == null ? null : "" + result.getPlace());
			rec.setString("longitude", result.getLongitude() == null ? null : "" + result.getLongitude());
			rec.setString("latitude", result.getLatitude() == null ? null : "" + result.getLatitude());
			rec.setString("visit_user", result.getVisitUser() == null ? null : "" + result.getVisitUser());
			rec.setString("userid", result.getUserid());
			rec.setString("checkin_time", D2Connector.formatDateTime(new Date(result.getCheckinTime())));
	
			Userlist user = users.get(result.getUserid());
			if(user != null)
			{
				rec.setString("userName", user.getName());
				rec.setString("userNo", user.getJobnumber());
			}
			else
			{
				rec.setString("userName", null);
				rec.setString("userNo", null);
			}
			
			KintoneFileList files = new KintoneFileList();
			
			for(String url: result.getImageList())
			{
				files.add(copyImage(url));
			}
			if(files.size() != 0)
			{
				rec.setFiles("image_list", files);
			}
			postRecs.add(rec);
		}
		
		if(postRecs.size() != 0)
		{
			postRecordsToKintone(postRecs);
		}
	}
	

	/**
	 * main
	 * @param args propter
	 * @throws Exception
	 */
	public static void main(String[] args)
		throws Exception
	{
		//add
		//------------------------------------------------------------------------------------------
		String date[] ={"2019-07-01","2019-07-30"};


		String appKey = "xxxxxxxxxxx";
		String appSecret = "xxxxxxxxxxx";
		String domain = "xxxxxxxxxxx.cybozu.cn";
		long appId = 115;
		long spaceId = 0;
		String apiToken = "xxxxxxxxxxx";
		//-------------------------------------------------------------------------------------------
		
		if(date.length < 2)
		{
			System.err.println("args[0]: start date(yyyy-mm-dd). args[1]: end date(yyyy-mm-dd).");
			System.exit(-1);
		}
		//modify
		D2CheckinConnector qyd2 = new D2CheckinConnector(appKey, appSecret, domain, appId, spaceId, apiToken);
		qyd2.execute(D2Connector.parseDate(date[0]), D2Connector.parseDate(date[1]));	
		
		System.out.println("success");
		
		// 開始日-終了日の設定
//		D2TimeCardResultConnector qyd2 = new D2TimeCardResultConnector("123456", "1234567890123456789012345678901234567890123", "test.cybozu.cn", 1, 0, "api_token-xxxxx");
//		qyd2.execute(D2Connector.parseDate(args[0]), D2Connector.parseDate(args[1]));
	}
}
